#include "SourceAttenuee.hpp"

#include "Algebre/Vecteur.hpp"

#include <cmath>

using namespace std;

/**
 * Constructeur usuel, qui permet de construire une SourceAttenuee à
 * la position voulue, d'une Couleur donnée et avec ses trois
 * coefficients d'atténuation.
 *
 * La version par défaut place une source noire à l'origine, qui n'a
 * pas d'atténuation en fonction de la distance.
 *
 * @param coul Couleur de la SourceAttenuee.
 * @param coord position de la SourceAttenuee.
 * @param c1 coefficient d'atténuation constant.
 * @param c2 coefficient d'atténuation linéraire
 * @param c3 coefficient d'atténuation quadratique.
 */
SourceAttenuee::SourceAttenuee(const Couleur& coul, const Coord& coord,
			       const double& c1, const double& c2,
			       const double& c3)
  : Source( coul, coord, srcAttenuee ), coeff1( c1 ), coeff2( c2 ), coeff3( c3 )
{}

/**
 * Constructeur de copie, permettant de dupliquer une SourceAttenuee.
 *
 * @param src instance de SourceAttenuee à copier.
 */
SourceAttenuee::SourceAttenuee(const SourceAttenuee& src)
  : Source( src.Color, src.Position, srcAttenuee ), coeff1( src.coeff1 ),
    coeff2( src.coeff2 ), coeff3( src.coeff3 )
{}

/**
 * Constructeur permettant de promouvoir une Source en SourceAttenuee.
 *
 * @param src instance de Source à promouvoir.
 */
SourceAttenuee::SourceAttenuee(const Source& src)
  : Source( src/*, srcAttenuee*/ ),  coeff1( 0. ), coeff2( 0. ), coeff3( 0. )
{}

/**
 * Le destructeur n'a rien de spécial à faire.
 */
SourceAttenuee::~SourceAttenuee()
{}

/**
 * Calcule le coefficient d'atténuation, en fonction de la position du
 * point éclairé.
 *
 * @return le coefficient d'atténuation, qui est borné pour plus de
 * sûreté.
 */
double SourceAttenuee::attenuation(const Coord& coord) const
{
  Vecteur dist( Position, coord );

  double module( sqrt( dist.norme() ) );

  return std::min( 1 / ( coeff1 + coeff2 * module + coeff3 * pow( module, 2 ) ),
		   1.);
}

/**
 * Permet d'accéder au coefficient d'atténuation constant.
 *
 * @return une référence constante sur coeff1.
 */
const double& SourceAttenuee::constant() const
{
  return coeff1;
}

/**
 * Permet d'accéder au coefficient d'atténuation linéaire.
 *
 * @return une référence constante sur coeff2.
 */
const double& SourceAttenuee::lineaire() const
{
  return coeff2;
}

/**
 * Permet d'accéder au coefficient d'atténuation quadratique.
 *
 * @return une référence constante sur coeff3.
 */
const double& SourceAttenuee::quadratique() const
{
  return coeff3;
}
